// Object.defineProperty( object, property, descriptor )
// 作用: 为 object 定义或配置 property 属性，并通过 descriptor 来设置 property 属性的特征
// 返回: 返回新定义了属性或配置了属性的对象(即defineProperty函数的第一个参数对应的对象)

const x = new Object();
console.log( x );

// 为指定的实例动态添加新属性
x.name = '李阿芳';
console.log( x );

// 动态从指定实例删除指定属性
delete x.name;
console.log( x );

// 用于描述属性的特征
const descriptor = {
    // 确定属性值 (若将 value 省略则属性值默认为 undefined)
    value: '赵德芳',
    // 指示属性是否可以被枚举 (默认值是 false ，表示属性不可被枚举)
    enumerable: true,
    // 指示属性值是否可以被更改 (默认值是false，表示属性值不可被更改)
    writable: true,
    // 所谓"配置"属性是指 修改属性的描述符(descriptor) 或 从指定对象上删除属性
    // 指示属性是否可以配置 (默认值是false，表示属性不可被配置)
    configurable: true
}

const y = Object.defineProperty( x, 'username' , descriptor );
console.log( x );
x.username = '李元芳';
console.log( x );

const anotherDescriptor = {
    value: '德芳',
    configurable: false
}

// 为已经存在的属性修改描述符(descriptor)
// 对于原本就有描述符的属性来说，新的描述符中有那些特征才更新那些特征
const z = Object.defineProperty( x, 'username', anotherDescriptor );
console.log( x );

// 尝试从 x 指向的对象(此处表示实例)上删除 username 属性
delete x.username;
console.log( x );

console.log( x === y );
console.log( x === z );